package com.retry.task.core.config;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import com.retry.task.core.exception.RetryTaskRuntimeException;
import com.retry.task.core.executor.ExectorAdapterImpl;
import com.retry.task.core.executor.IExectorAdapter;
import com.retry.task.core.executor.IExecutor;
import com.retry.task.core.executor.impl.ClientExecutor;
import com.retry.task.core.server.RetryTaskServer;
import com.retry.task.core.utils.threadPool.RetryTaskThreadPoolExector;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author gao.gwq
 * @version 1.0
 * @date 2022/5/8  08:20
 * @Description TODO
 */
public class ClientServerService {

    private static final Logger LOGGER = LoggerFactory.getLogger(ClientServerService.class);

    private RetryTaskServer retryTaskServer;

    private volatile boolean flag = false;

    private ClientServerService() {}

    private static final class InnerClass {
        private static final ClientServerService clientServerService = new ClientServerService();
    }

    public static ClientServerService getInstance() {
        return InnerClass.clientServerService;
    }

    public synchronized void initClientServer(Integer clientPort) {
        if (flag == true) {
            throw new RetryTaskRuntimeException("client server is already start");
        }
        RetryTaskThreadPoolExector taskThreadPoolExector = new RetryTaskThreadPoolExector(
            2,
            200,
            60L,
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<Runnable>(),
            new BasicThreadFactory.Builder().namingPattern("retry-task-client-server").build(),
            new RejectedExecutionHandler() {
                @Override
                public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                    throw new RuntimeException("RetryTaskServer bizThreadPool is EXHAUSTED!");
                }
            });
        IExectorAdapter exectorAdapter = new ExectorAdapterImpl(new ClientExecutor());
        retryTaskServer = new RetryTaskServer(taskThreadPoolExector, exectorAdapter, clientPort);
        retryTaskServer.start();
        flag = true;
        LOGGER.info("retry-task client server start up sucess");
    }
}
